package com.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.constant.VideoConstant;
import com.domain.Video;
import com.domain.VideoCollection;
import com.exception.ConditionException;
import com.mapper.VideoCollectionDao;
import com.mapper.VideoDao;
import com.service.VideoCollectionService;
import io.netty.util.internal.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.constant.VideoConstant.VIDEO_COLLECTION_KEY;

@Service
public class VideoCollectionServiceImpl extends ServiceImpl<VideoCollectionDao, VideoCollection> implements VideoCollectionService {

    @Autowired
    private VideoDao videoDao;

    @Autowired
    private RedisTemplate<String, String> redis;

    @Autowired
    private VideoCollectionDao videoCollectionDao;

    /**
     * 用户收藏视频
     * TODO 可以用 redis 记录视频的收藏数
     * <p>
     * 先操作数据库（添加一条记录），后删除redis缓存
     */
    @Transactional
    public void addVideoCollection(VideoCollection videoCollection, Long userId) {
        Long videoId = videoCollection.getVideoId();
        Long groupId = videoCollection.getGroupId();
        if (videoId == null || groupId == null) {
            throw new ConditionException("参数异常");
        }
        QueryWrapper<Video> videoQueryWrapper = new QueryWrapper<>();
        videoQueryWrapper.lambda().eq(Video::getId, videoId);
        Video video = videoDao.selectOne(videoQueryWrapper);
        if (video == null) {
            throw new ConditionException("非法视频");
        }
//        //先删除后添加
//        videoDao.deleteVideoCollection(videoId, userId);
//        videoCollection.setUserId(userId);
//        videoCollection.setCreateTime(new Date());
//        videoDao.addVideoCollection(videoCollection);

        //先操作数据库（添加一条记录），后删除redis缓存
        videoCollection.setUserId(userId);
        videoCollection.setCreateTime(new Date());
        videoCollectionDao.addVideoCollection(videoCollection);
        String videoCollectionKey = VideoConstant.VIDEO_COLLECTION_KEY + videoCollection.getId();
        redis.delete(videoCollectionKey);
    }

    /**
     * 取消收藏视频
     * <p>
     * 先删除数据库的记录，然后删除 redis 缓存
     */
    public void deleteVideoCollection(Long videoId, Long userId) {
        QueryWrapper<Video> videoQueryWrapper = new QueryWrapper<>();
        videoQueryWrapper.lambda().eq(Video::getId, videoId);
        Video video = videoDao.selectOne(videoQueryWrapper);
        //判断视频存不存在
        if (video == null) {
            throw new ConditionException("非法视频！");
        }
        //判断这个视频之前有没有被这个用户收藏过，如果没有，就不用进行下一步了
        VideoCollection videoCollection = videoCollectionDao.getVideoCollectionsByVideoIdAndUserId(videoId, userId);
        if (videoCollection == null) {
            throw new ConditionException("您没有收藏过本视频，无法取消收藏");
        }
        videoCollectionDao.deleteVideoCollection(videoId, userId);
        String videoCollectionKey = VideoConstant.VIDEO_COLLECTION_KEY + videoId;
        redis.delete(videoCollectionKey);
    }

    /**
     * 查询视频当前被多少用户收藏
     * TODO 如何用 redis 判断用户是否收藏过该视频
     * <p>
     * 先查redis，如果redis没有，再查数据库，同时同步一份数据到 redis（时效30分钟）；如果redis有，就从redis查询数据并返回
     */
    public Map<String, Object> getVideoCollections(Long videoId, Long userId) {
        String videoCollectionKey = VIDEO_COLLECTION_KEY + videoId;
        String videoCollectionCountStr = redis.opsForValue().get(videoCollectionKey);
        Long count;
        if (StringUtil.isNullOrEmpty(videoCollectionCountStr)) {
            count = videoCollectionDao.getVideoCollections(videoId);
            redis.opsForValue().set(VIDEO_COLLECTION_KEY + videoId, String.valueOf(count), 30L, TimeUnit.MINUTES);
        } else {
            count = Long.valueOf(videoCollectionCountStr);
        }

        //在数据库中查询用户是否收藏过该视频
        VideoCollection videoCollection = videoCollectionDao.getVideoCollectionsByVideoIdAndUserId(videoId, userId);
        boolean like = (videoCollection != null);
        //我们不仅返回视频收藏量，如果当前是用户登录状态且收藏了该视频，我们还会返回true，那么在前端的收藏按钮就会高亮显示，表示当前登录用户收藏了这个视频
        Map<String, Object> result = new HashMap<>();
        result.put("count", count);
        result.put("like", like);
        return result;
    }


}
